package org.jiuling.camera.yinshi;

import com.alibaba.fastjson.JSON;
import org.jiuling.camera.yinshi.config.YinShiConfig;
import org.jiuling.camera.yinshi.enums.*;
import org.jiuling.camera.yinshi.model.YinShiDeviceInfoModel;
import org.jiuling.camera.yinshi.model.YinShiDeviceModel;
import org.jiuling.camera.yinshi.model.YinShiLiveAddrModel;
import org.jiuling.camera.yinshi.model.YinShiTokenModel;
import org.jiuling.local.tools.exception.LocalToolsException;
import org.jiuling.local.tools.verify.IntegerVerify;
import org.jiuling.local.tools.verify.ObjectVerify;
import org.jiuling.local.tools.verify.StringVerify;
import org.jiuling.network.tools.http.request.HttpRequest;
import org.jiuling.network.tools.http.request.enums.RequestMethodEnum;
import org.jiuling.network.tools.http.request.exception.RequestException;
import org.jiuling.network.tools.http.request.factory.HttpRequestFactory;
import org.jiuling.network.tools.http.request.model.HttpRequestParam;
import org.jiuling.network.tools.response.ResponseData;
import org.jiuling.network.tools.response.verify.ResponseDataVerify;

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.List;

/**
 * 萤石云
 * @author 紫灵
 * @date 2022年10月28日 13时28分25秒
 */
public class YinShiCloud {

    /** 萤石云配置 */
    private final YinShiConfig yinShiConfig;
    /** 萤石云Token */
    private YinShiTokenModel yinShiToken;

    public YinShiCloud(YinShiConfig yinShiConfig) {
        this.yinShiConfig = yinShiConfig;
    }

    /**
     * 获取Token
     * @return token
     */
    public String getToken(){
        if(ObjectVerify.isNull(this.yinShiToken)){
            realTimeGetToken();
        }
        if(this.yinShiToken.getExpireTime() < System.currentTimeMillis()){
            realTimeGetToken();
        }
        realTimeGetToken();
        return this.yinShiToken.getAccessToken();
    }

    /**
     * 实时获取Token
     */
    private void realTimeGetToken(){
        HttpRequest httpRequest = new HttpRequest();
        try {
            HttpRequestFactory httpRequestFactory = httpRequest.openHttpRequestFactory(YinShiApiEnum.GET_TOKEN.getApi());
            // 请求内容
            HttpRequestParam httpRequestParam = new HttpRequestParam().add("appKey",yinShiConfig.getAppKey()).add("appSecret",yinShiConfig.getAppSecret());
            httpRequestFactory.setRequestMethod(RequestMethodEnum.POST);
            httpRequestFactory.setRequestParam(httpRequestParam);
            this.yinShiToken = JSON.parseObject(JSON.toJSONString(ResponseDataVerify.verifyAndrReturnData(JSON.parseObject(httpRequest.send().getBody(), ResponseData.class),200)),YinShiTokenModel.class);
        } catch (RequestException | IOException | LocalToolsException | NoSuchAlgorithmException |
                 KeyManagementException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取设备列表
     * @return 设备列表
     */
    public List<YinShiDeviceModel> getDeviceList() {
        HttpRequest httpRequest = new HttpRequest();
        try {
            HttpRequestFactory httpRequestFactory = httpRequest.openHttpRequestFactory(YinShiApiEnum.GET_DEVICE_LIST.getApi());
            // 请求内容
            HttpRequestParam httpRequestParam = new HttpRequestParam().add("accessToken",getToken()).add("pageStart",0).add("pageSize",10);
            httpRequestFactory.setRequestMethod(RequestMethodEnum.POST);
            httpRequestFactory.setRequestParam(httpRequestParam);
            return JSON.parseArray(JSON.toJSONString(ResponseDataVerify.verifyAndrReturnData(JSON.parseObject(httpRequest.send().getBody(), ResponseData.class),200)),YinShiDeviceModel.class);
        } catch (RequestException | IOException | LocalToolsException | NoSuchAlgorithmException |
                 KeyManagementException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取设备信息
     * @param deviceSerial 设备序列号
     * @return 设备信息模型
     */
    public YinShiDeviceInfoModel getDeviceInfo(String deviceSerial){
        HttpRequest httpRequest = new HttpRequest();
        try {
            HttpRequestFactory httpRequestFactory = httpRequest.openHttpRequestFactory(YinShiApiEnum.GET_DEVICE_INFO.getApi());
            // 请求内容
            HttpRequestParam httpRequestParam = new HttpRequestParam().add("accessToken",getToken()).add("deviceSerial",deviceSerial);
            httpRequestFactory.setRequestMethod(RequestMethodEnum.POST);
            httpRequestFactory.setRequestParam(httpRequestParam);
            return JSON.parseObject(JSON.toJSONString(ResponseDataVerify.verifyAndrReturnData(JSON.parseObject(httpRequest.send().getBody(), ResponseData.class),200)), YinShiDeviceInfoModel.class);
        } catch (RequestException | IOException | LocalToolsException | NoSuchAlgorithmException |
                 KeyManagementException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取捕获图片地址
     * @param deviceSerial 设备序列号
     */
    public String grtCaptureImgUrl(String deviceSerial){
        HttpRequest httpRequest = new HttpRequest();
        try {
            HttpRequestFactory httpRequestFactory = httpRequest.openHttpRequestFactory(YinShiApiEnum.GRT_CAPTURE_IMG_URL.getApi());
            // 请求内容
            HttpRequestParam httpRequestParam = new HttpRequestParam().add("accessToken",getToken()).add("deviceSerial",deviceSerial);
            httpRequestFactory.setRequestMethod(RequestMethodEnum.POST);
            httpRequestFactory.setRequestParam(httpRequestParam);
//            System.out.println(ResponseDataVerify.verifyAndrReturnData(JSON.parseObject(httpRequest.send().getBody(), ResponseData.class),200));
            return JSON.parseObject(JSON.toJSONString(ResponseDataVerify.verifyAndrReturnData(JSON.parseObject(httpRequest.send().getBody(), ResponseData.class),200))).get("picUrl").toString();
        } catch (RequestException | IOException | LocalToolsException | NoSuchAlgorithmException |
                 KeyManagementException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 云台停止
     * @param deviceSerial 设备序列号
     * @param channelNo 通道号
     * @param direction 方向
     */
    public void panTiltStop(String deviceSerial,int channelNo,DirectionEnum direction){
        HttpRequest httpRequest = new HttpRequest();
        try {
            HttpRequestFactory httpRequestFactory = httpRequest.openHttpRequestFactory(YinShiApiEnum.PAN_TILT_STOP.getApi());
            // 请求内容
            HttpRequestParam httpRequestParam = new HttpRequestParam()
                    .add("accessToken",getToken())
                    .add("deviceSerial",deviceSerial)
                    .add("channelNo",channelNo);
            if(!ObjectVerify.isNull(direction)){
                httpRequestParam.add("direction",direction.getCode());
            }
            httpRequestFactory.setRequestMethod(RequestMethodEnum.POST);
            httpRequestFactory.setRequestParam(httpRequestParam);
            ResponseDataVerify.verifyAndrReturnData(JSON.parseObject(httpRequest.send().getBody(), ResponseData.class),200);
        } catch (RequestException | IOException | LocalToolsException | NoSuchAlgorithmException |
                 KeyManagementException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 云台开始
     * @param deviceSerial 设备序列号
     * @param channelNo 通道号
     * @param direction 方向
     * @param speed 速度
     */
    public void panTiltStart(String deviceSerial, int channelNo, DirectionEnum direction, SpeedEnum speed){
        panTiltStop(deviceSerial,channelNo,direction);
        HttpRequest httpRequest = new HttpRequest();
        try {
            HttpRequestFactory httpRequestFactory = httpRequest.openHttpRequestFactory(YinShiApiEnum.PAN_TILT_START.getApi());
            // 请求内容
            HttpRequestParam httpRequestParam = new HttpRequestParam()
                    .add("accessToken",getToken())
                    .add("deviceSerial",deviceSerial)
                    .add("channelNo",channelNo)
                    .add("direction",direction.getCode())
                    .add("speed",speed.getCode());
            httpRequestFactory.setRequestMethod(RequestMethodEnum.POST);
            httpRequestFactory.setRequestParam(httpRequestParam);
            ResponseDataVerify.verifyAndrReturnData(JSON.parseObject(httpRequest.send().getBody(), ResponseData.class),200);
        } catch (RequestException | IOException | LocalToolsException | NoSuchAlgorithmException |
                 KeyManagementException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取直播地址
     * @param deviceSerial 设备序列号
     * @param channelNo 通道号 非必填 默认为1
     * @param code ezopen协议地址的设备的视频加密密码
     * @param expireTime 过期时长，单位秒；针对hls/rtmp设置有效期，相对时间；30秒-7天
     * @param protocol 流播放协议
     * @param quality 视频清晰度
     * @param startTime 本地录像/云存储录像回放开始时间,示例：2019-12-01 00:00:00
     * @param stopTime 本地录像/云存储录像回放结束时间,示例：2019-12-01 00:00:00
     * @param type 地址的类型
     * @param supportH265 请判断播放端是否要求播放视频为H265编码格式,1表示需要，0表示不要求
     * @param gbchannel 国标设备的通道编号
     * @return 播放地址
     */
    public YinShiLiveAddrModel getLiveAddr(String deviceSerial, Integer channelNo, String code, Integer expireTime, PlayBackProtocolEnum protocol, QualityEnum quality, String startTime, String stopTime, LiveTypeEnum type, Integer supportH265, String gbchannel){
        HttpRequest httpRequest = new HttpRequest();
        try {
            HttpRequestFactory httpRequestFactory = httpRequest.openHttpRequestFactory(YinShiApiEnum.GET_LIVE_ADDR.getApi());
            // 请求参数
            HttpRequestParam httpRequestParam = new HttpRequestParam()
                    .add("accessToken",getToken())
                    .add("deviceSerial",deviceSerial);
            if(!IntegerVerify.isBlank(channelNo)){
                httpRequestParam.add("channelNo",channelNo);
            }
            if(!StringVerify.isBlank(code)) {
                httpRequestParam.add("code", code);
            }
            if(!IntegerVerify.isBlank(expireTime)) {
                httpRequestParam.add("expireTime",expireTime);
            }
            if(!ObjectVerify.isNull(protocol)) {
                httpRequestParam.add("protocol", protocol.getCode());
            }
            if(!ObjectVerify.isNull(quality)) {
                httpRequestParam.add("quality", quality.getCode());
            }
            if(!StringVerify.isBlank(startTime) && !StringVerify.isBlank(stopTime)) {
                httpRequestParam.add("startTime",startTime);
                httpRequestParam.add("stopTime",stopTime);
            }
            if(!ObjectVerify.isNull(type)) {
                httpRequestParam.add("type",type.getCode());
            }
            if(!IntegerVerify.isBlank(supportH265)) {
                httpRequestParam.add("supportH265", supportH265);
            }
            if(!StringVerify.isBlank(gbchannel)) {
                httpRequestParam.add("gbchannel",gbchannel);
            }
            httpRequestFactory.setRequestMethod(RequestMethodEnum.POST);
            httpRequestFactory.setRequestParam(httpRequestParam);
            return JSON.parseObject(JSON.toJSONString(ResponseDataVerify.verifyAndrReturnData(JSON.parseObject(httpRequest.send().getBody(), ResponseData.class),200)), YinShiLiveAddrModel.class);
        }catch (RequestException | IOException | LocalToolsException | NoSuchAlgorithmException |
                KeyManagementException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        YinShiConfig yinShiConfig1 = new YinShiConfig();
        yinShiConfig1.setAppKey("4c834543998c4ea88797ae3f776a6c4c");
        yinShiConfig1.setAppSecret("1a4e3809251bb1e38355503d92f8695e");
        YinShiCloud yinShiCloud = new YinShiCloud(yinShiConfig1);
//        System.out.println(JSON.toJSONString(yinShiCloud.getLiveAddr("J16112608",1,null,null,PlayBackProtocolEnum.EZOPEN,QualityEnum.HIGH_DEFINITION,null,null,null,null,null)));
//        yinShiCloud.getLiveAddr("J16112608",1,null,null,null,1,null,null,null,null,null);
//        System.out.println(yinShiCloud.grtCaptureImgUrl("J16112608"));
//        yinShiCloud.getDeviceList().forEach(yinShiDeviceModel -> System.out.println(JSON.toJSONString(yinShiDeviceModel)));
//        yinShiCloud.panTiltStop("J16112608",1,null);
        while (true){
            try {
                yinShiCloud.panTiltStart("J16112608",1,DirectionEnum.LEFT,SpeedEnum.MODERATION);
                Thread.sleep (30000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

        }
//        yinShiCloud.panTiltStop("J16112608",1,null);
//        System.out.println(yinShiCloud.grtCaptureImgUrl("J16112608"));
//        System.out.println();
//        System.out.println();
    }


}
